package com.turbo.cloud.ums.web.logic;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.turbo.cloud.core.base.PageQuery;
import com.turbo.cloud.core.exception.BusinessException;
import com.turbo.cloud.core.security.utils.SecurityUtil;
import com.turbo.cloud.ums.constants.UMSConstants;
import com.turbo.cloud.ums.web.entity.*;
import com.turbo.cloud.core.utils.PageUtil;
import com.turbo.cloud.ums.web.model.role.*;
import com.turbo.cloud.ums.web.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 菜单表 逻辑处理类
 * </p>
 *
 * @author zhangluning
 * @since 2022-08-13
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class RoleLogic {

    final IUmsRoleService umsRoleService;
    final IUmsApiService umsApiService;
    final IUmsRolePermissionRelationService umsRolePermissionRelationService;

    /**
     * 根据当前系统ID，查询角色分页列表
     *
     * @return Page
     */
    public Page<UmsRoleVo> queryRolePage(PageQuery<UmsRoleQo> pageQuery) {
        UmsRoleQo umsRoleQo = PageUtil.getPageQueryParam(pageQuery, UmsRoleQo::new);

        LambdaQueryWrapper<UmsRole> roleLQW = new LambdaQueryWrapper<>();
        roleLQW.eq(UmsRole::getSystemId, SecurityUtil.getCurrentSystemId());

        roleLQW.like(CharSequenceUtil.isNotBlank(umsRoleQo.getRoleNameByLike()), UmsRole::getRoleName, umsRoleQo.getRoleNameByLike());
        roleLQW.like(CharSequenceUtil.isNotBlank(umsRoleQo.getRoleCodeByLike()), UmsRole::getRoleCode, umsRoleQo.getRoleCodeByLike());
        roleLQW.eq(Objects.nonNull(umsRoleQo.getStateId()), UmsRole::getStateId, umsRoleQo.getStateId());

        roleLQW.orderByAsc(UmsRole::getSort);
        Page<UmsRole> rolePage = umsRoleService.page(pageQuery.toPage(), roleLQW);

        Page<UmsRoleVo> rolePageView = PageUtil.toPageView(rolePage, UmsRoleVo::new);

        if (Objects.nonNull(rolePageView.getRecords())) {
            for (UmsRoleVo umsRoleVo : rolePageView.getRecords()) {
                umsRoleVo.setStateValue(1 == umsRoleVo.getStateId());

                LambdaQueryWrapper<UmsRolePermissionRelation> permissionMenuRelationLQW = new LambdaQueryWrapper<>();
                permissionMenuRelationLQW.eq(UmsRolePermissionRelation::getRoleId, umsRoleVo.getId());
                List<UmsRolePermissionRelation> roleMenuListByRoleId = umsRolePermissionRelationService.list(permissionMenuRelationLQW);

                List<String> permissionIdsByRole = roleMenuListByRoleId.stream().map(UmsRolePermissionRelation::getPermissionId).toList();
                umsRoleVo.setPermissionIds(permissionIdsByRole);
            }
        }

        return rolePageView;
    }

    /**
     * 新增角色
     *
     * @param umsRoleDo 实体
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean createRole(UmsRoleDo umsRoleDo) {
        umsRoleDo.setSystemId(SecurityUtil.getCurrentSystemId());

        LambdaQueryWrapper<UmsRole> roleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        roleLambdaQueryWrapper.eq(UmsRole::getRoleCode, umsRoleDo.getRoleCode());
        UmsRole umsRoleTmp = umsRoleService.getOne(roleLambdaQueryWrapper);
        if (Objects.nonNull(umsRoleTmp)) {
            throw new BusinessException("角色编码已经存在，请更换");
        }

        UmsRole umsRole = new UmsRole();
        BeanUtils.copyProperties(umsRoleDo, umsRole);

        boolean roleSaveResult = umsRoleService.save(umsRole);
        if (!roleSaveResult) {
            throw new BusinessException("新增角色失败");
        }
        return true;
    }

    /**
     * 修改角色
     *
     * @param umsRoleDo 实体
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean modifyRole(UmsRoleDo umsRoleDo) {

        UmsRole umsRoleTmp = umsRoleService.getById(umsRoleDo.getId());

        if (Objects.nonNull(umsRoleTmp) && !umsRoleTmp.getRoleCode().equals(umsRoleDo.getRoleCode())) {
            LambdaQueryWrapper<UmsRole> roleLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roleLambdaQueryWrapper.eq(UmsRole::getRoleCode, umsRoleDo.getRoleCode());
            UmsRole umsRole = umsRoleService.getOne(roleLambdaQueryWrapper);
            if (Objects.nonNull(umsRole)) {
                throw new BusinessException("角色编码已经存在，请更换");
            }
        }

        UmsRole umsRole = new UmsRole();
        BeanUtils.copyProperties(umsRoleDo, umsRole);

        boolean result = umsRoleService.updateById(umsRole);
        if (!result) {
            throw new BusinessException("修改角色失败");
        }

        return true;
    }

    /**
     * 开启、关闭角色有效状态
     *
     * @param id 角色ID
     */
    public Boolean enabledRoleStateById(String id) {
        UmsRole umsRole = umsRoleService.getById(id);
        if (Objects.isNull(umsRole)) {
            throw new BusinessException("角色不存在");
        }

        if (UMSConstants.DICT_STATE_ID_YES.equals(umsRole.getStateId())) {
            umsRole.setStateId(0);
        } else {
            umsRole.setStateId(1);
        }

        boolean result = umsRoleService.updateById(umsRole);
        if (!result) {
            throw new BusinessException("修改角色状态失败");
        }
        return true;
    }

    /**
     * 删除角色
     *
     * @param id 角色ID
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean removeRoleById(String id) {
        if (StrUtil.isBlank(id)) {
            throw new BusinessException("角色ID不能为空");
        }

        boolean result = umsRoleService.removeById(id);

        //删除角色和菜单的关联关系
        LambdaQueryWrapper<UmsRolePermissionRelation> roleMenuRelationLQW = new LambdaQueryWrapper<>();
        roleMenuRelationLQW.eq(UmsRolePermissionRelation::getRoleId, id);
        umsRolePermissionRelationService.remove(roleMenuRelationLQW);

        if (!result) {
            throw new BusinessException("删除角色失败");
        }
        return true;
    }

    /**
     * 绑定角色和权限关系
     *
     * @param umsRolePermissionRelationDo 实体
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean bindRolePermissionRelation(UmsRolePermissionRelationDo umsRolePermissionRelationDo) {
        if (StrUtil.isNotBlank(umsRolePermissionRelationDo.getPermissionId())) {
            UmsRolePermissionRelation umsRolePermissionRelation = new UmsRolePermissionRelation();
            BeanUtils.copyProperties(umsRolePermissionRelationDo, umsRolePermissionRelation);
            umsRolePermissionRelationService.save(umsRolePermissionRelation);
        } else {
            // 如果批量添加，这里把以前的关联关系都进行了解绑
            LambdaQueryWrapper<UmsRolePermissionRelation> rolePermissionRelationLQW = new LambdaQueryWrapper<>();
            rolePermissionRelationLQW.eq(UmsRolePermissionRelation::getRoleId, umsRolePermissionRelationDo.getRoleId());
            umsRolePermissionRelationService.remove(rolePermissionRelationLQW);

            if (!CollectionUtils.isEmpty(umsRolePermissionRelationDo.getPermissionIds())) {
                List<UmsRolePermissionRelation> list = new ArrayList<>();
                for (String permissionId : umsRolePermissionRelationDo.getPermissionIds()) {
                    UmsRolePermissionRelation umsRolePermissionRelation = new UmsRolePermissionRelation();
                    umsRolePermissionRelation.setRoleId(umsRolePermissionRelationDo.getRoleId());
                    umsRolePermissionRelation.setPermissionId(permissionId);
                    list.add(umsRolePermissionRelation);
                }
                umsRolePermissionRelationService.saveBatch(list);
            }
        }
        return true;
    }

    /**
     * 解绑角色和权限关系
     *
     * @param umsRolePermissionRelationDo 实体
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean unBindRolePermissionRelation(UmsRolePermissionRelationDo umsRolePermissionRelationDo) {
        LambdaQueryWrapper<UmsRolePermissionRelation> rolePermissionRelationLQW = new LambdaQueryWrapper<>();
        rolePermissionRelationLQW.eq(UmsRolePermissionRelation::getRoleId, umsRolePermissionRelationDo.getRoleId());
        rolePermissionRelationLQW.eq(UmsRolePermissionRelation::getPermissionId, umsRolePermissionRelationDo.getPermissionId());
        boolean result = umsRolePermissionRelationService.remove(rolePermissionRelationLQW);
        if (!result) {
            throw new BusinessException("解除角色和权限关系失败");
        }
        return true;
    }
}
